#include <sys/stat.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <pthread.h>
#include <errno.h>
#include "messageReader.h"
#include "protocol.h"
#include "room.h"
#define MYPORT 4000
#define BACKLOG 10

void *start_thread(void *arg);

int main(int argc, char* argv[]){
	unsigned short port=MYPORT;
	if(argc==2)
		port=atoi(argv[1]);
	int ssock;
	if((ssock=socket(AF_INET,SOCK_STREAM,0))==-1){
		perror("socket");
		exit(1);
	}
	struct sockaddr_in serv_addr;
	memset(&serv_addr, 0, sizeof(serv_addr));

	serv_addr.sin_family=AF_INET;
	serv_addr.sin_port=htons(port);
	serv_addr.sin_addr.s_addr=INADDR_ANY;
	if(bind(ssock,(struct sockaddr*)&serv_addr,	
				sizeof(struct sockaddr))==-1){
		perror("bind");
		exit(1);
	}
	//메세지 처리기 쓰레드 시작
	pthread_t read_tid;
	if(pthread_create(&read_tid, NULL, messageReader, NULL)!=0){
		perror("failed to create messageReader thread");
		exit(1);
	}
	if(listen(ssock,BACKLOG)==-1){
		perror("listen");
		exit(1);
	}

	pthread_t client_tid;
	pthread_attr_t attr;
	//클라이언트 쓰레드를 detach로 만들어 
	//쓰레드 종료시 자원 반환을 시키도록 함.
	if(pthread_attr_init(&attr)!=0){
		perror("pthread_attr_init");
		exit(1);
	}
	if(pthread_attr_setdetachstate(&attr,PTHREAD_CREATE_DETACHED)!=0){
		perror("pthread_setdetach");
		exit(1);
	}

	int cnt=0;

	while(1){
		int sin_size=sizeof(struct sockaddr_in);
		int csock;
		struct sockaddr_in clnt_addr;
		if((csock=accept(ssock,(struct sockaddr*)&clnt_addr,
				&sin_size))==-1){
			perror("accept");
			continue;
		}
		fprintf(stderr,"클라이언트가 접속하였습니다.\n");
		//쓰레드 할당
		if(pthread_create(&client_tid, &attr, 
					start_thread,(void*)&csock)==-1){
			perror("failed to create cilent thread");
			exit(1);
		}
		cnt++;
	}
	close(ssock);
}

void *start_thread(void *arg){
	const int fd=*(int*)arg;
	unsigned char buf[MESSAGE_SIZE];
	while(1){
		int numbytes=0;
		while((numbytes=recv(fd,buf,MESSAGE_SIZE,0))<0 
				&& errno==EWOULDBLOCK);
		if(numbytes<=0){
			printf("%d 접속 종료\n",fd);
			struct person *curPerson=findPerson(fd);
			if(curPerson!=NULL){
		//		printf("강제종료됨\n");
				exitPerson(curPerson);
			}
			close(fd);
			pthread_exit(0);
		}
		//printf("read Message : %d\n",numbytes);

		writeMessage(buf,numbytes,fd);
	}
}
